import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:provider/provider.dart';

import '../../extension/extension_color.dart';
import '../../extension/extension_num.dart';
import '../../extension/extension_text_style.dart';
import '../../helper/device_helper.dart';
import '../base/base_view_model.dart';

class BaseRootNew<T1 extends ChangeNotifier, T2 extends ChangeNotifier, T3 extends ChangeNotifier, T4 extends ChangeNotifier,
    T5 extends ChangeNotifier, T6 extends ChangeNotifier> extends StatefulWidget {
  final Widget? body;
  final String? title;
  final List<Widget>? actions;
  final double? elevation;
  final bool centerTitle;
  final bool canBack;
  final VoidCallback? clickBack;
  final Color? bgColor;
  final Color? barColor;
  final T1? model1;
  final T2? model2;
  final T3? model3;
  final T4? model4;
  final T5? model5;
  final T6? model6;
  final bool resizeToAvoidBottomInset;
  final bool belowStatusBar;
  final PreferredSizeWidget? bottom;
  final bool? wantKeepAlive;
  final bool isDarkTheme;
  final PopInvokedCallback? onPopInvoked;
  final bool primary;

  /// 状态栏style
  final SystemUiOverlayStyle? style;
  final Widget? bottomNavigationBar;

  const BaseRootNew({
    super.key,
    this.body,
    this.title,
    this.actions,
    this.elevation,
    this.centerTitle = true,
    this.canBack = true,
    this.clickBack,
    this.bgColor,
    this.barColor,
    this.model1,
    this.model2,
    this.model3,
    this.model4,
    this.model5,
    this.model6,
    this.resizeToAvoidBottomInset = false,
    this.belowStatusBar = true,
    this.style,
    this.bottom,
    this.wantKeepAlive,
    this.isDarkTheme = false,
    this.onPopInvoked,
    this.primary = true,
    this.bottomNavigationBar,
  });

  @override
  State<BaseRootNew<T1, T2, T3, T4, T5, T6>> createState() => _BaseRootNewState<T1, T2, T3, T4, T5, T6>();
}

class _BaseRootNewState<
    T1 extends ChangeNotifier,
    T2 extends ChangeNotifier,
    T3 extends ChangeNotifier,
    T4 extends ChangeNotifier,
    T5 extends ChangeNotifier,
    T6 extends ChangeNotifier> extends State<BaseRootNew<T1, T2, T3, T4, T5, T6>> with AutomaticKeepAliveClientMixin {
  var mList = [];

  @override
  void initState() {
    super.initState();
    if (null != widget.model1) mList.add(widget.model1);
    if (null != widget.model2) mList.add(widget.model2);
    if (null != widget.model3) mList.add(widget.model3);
    if (null != widget.model4) mList.add(widget.model4);
    if (null != widget.model5) mList.add(widget.model5);
    if (null != widget.model6) mList.add(widget.model6);
    if (mList.isNotEmpty) {
      for (var model in mList) {
        if (model is BaseViewModel) model.initState();
      }
    }
  }

  @override
  void dispose() {
    if (mList.isNotEmpty) {
      for (var model in mList) {
        if (model is BaseViewModel) model.dispose();
      }
    }
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    if (widget.wantKeepAlive ?? false) super.build(context);
    if (mList.isNotEmpty) {
      for (var model in mList) {
        if (model is BaseViewModel) model.setBuildContext(context);
      }
    }
    Widget child;
    if (mList.isNotEmpty) {
      child = MultiProvider(
        providers: [
          if (null != widget.model1) ChangeNotifierProvider<T1?>.value(value: widget.model1),
          if (null != widget.model2) ChangeNotifierProvider<T2?>.value(value: widget.model2),
          if (null != widget.model3) ChangeNotifierProvider<T3?>.value(value: widget.model3),
          if (null != widget.model4) ChangeNotifierProvider<T4?>.value(value: widget.model4),
          if (null != widget.model5) ChangeNotifierProvider<T5?>.value(value: widget.model5),
          if (null != widget.model6) ChangeNotifierProvider<T6?>.value(value: widget.model6),
        ],
        builder: (_, child) => widget.body ?? const Placeholder(),
        // child: widget.body,
      );
    } else {
      child = widget.body ?? const Placeholder();
    }
    child = Scaffold(
      appBar: null == widget.title
          ? (widget.belowStatusBar
              ? PreferredSize(
                  preferredSize: Size.fromHeight(DeviceHelper.topBarHeight * 0.07),
                  child: const SafeArea(
                    top: true,
                    child: SizedBox(),
                  ),
                )
              : null)
          : MyAppBar(
              context,
              title: widget.title,
              actions: widget.actions,
              elevation: widget.elevation,
              barColor: widget.barColor,
              canBack: widget.canBack,
              clickBack: widget.clickBack,
              centerTitle: widget.centerTitle,
              bottom: widget.bottom,
              isDarkTheme: widget.isDarkTheme,
            ),
      resizeToAvoidBottomInset: widget.resizeToAvoidBottomInset,
      body: SafeArea(child: child),
      backgroundColor: widget.bgColor ?? Colors.white,
      primary: widget.primary,
      bottomNavigationBar: widget.bottomNavigationBar,
    );
    if (null != widget.style) {
      child = AnnotatedRegion<SystemUiOverlayStyle>(
        value: widget.style!,
        child: child,
      );
    }
    if (null != widget.onPopInvoked) {
      child = PopScope(
        canPop: false,
        onPopInvoked: widget.onPopInvoked,
        child: child,
      );
    }
    return child;
  }

  @override
  bool get wantKeepAlive => widget.wantKeepAlive ?? false;
}

class MyAppBar extends AppBar {
  MyAppBar(
    BuildContext context, {
    Key? key,
    String? title,
    List<Widget>? actions,
    double? elevation,
    Color? barColor,
    bool? canBack,
    VoidCallback? clickBack,
    bool centerTitle = true,
    PreferredSizeWidget? bottom,
    bool? isDarkTheme,
  })  : assert(title is String || title is Widget || title == null),
        super(
          key: key,
          centerTitle: centerTitle,
          title: Text(title!, style: Colors.black87.toStyle(36.px).withBold),
          elevation: elevation ?? 1.px,
          shadowColor: Colors.grey,
          surfaceTintColor: Colors.white,
          scrolledUnderElevation: elevation ?? 1.px,
          leading: canBack == true && Navigator.canPop(context)
              ? IconButton(
                  icon: Icon(
                    Icons.arrow_back_ios,
                    color: Colors.black87,
                    size: 40.px,
                  ),
                  onPressed: clickBack ??
                      () {
                        Navigator.of(context).pop();
                      },
                )
              : const SizedBox(),
          actions: actions,
          titleSpacing: NavigationToolbar.kMiddleSpacing,
          backgroundColor: barColor ?? Colors.white,
          systemOverlayStyle: (isDarkTheme ?? false) ? SystemUiOverlayStyle.light : SystemUiOverlayStyle.dark,
          bottom: bottom,
        );
}
